﻿using System;
using System.Linq;
using ClrExtensions.Net.Rest;
using AddExtensions;

namespace MyNetflix2
{
    public class RestCalls
    {
        #region enums

        public enum QueueSortOrder { QueueSequence, DateAdded, Alphabetical }
        public enum DiscFormat { DVD, BluRay, NONE }

        #endregion

        #region Locals

        private static readonly string BaseUrl = "http://api.netflix.com/";

        #endregion

        #region RestCalls

        //--------------------------------------------------------------------------------
        // Get the Access Token from netFlix
        //--------------------------------------------------------------------------------
        public static RestCall GetAccessToken()
        {
            return new RestCall(RestVerb.Get, BaseUrl + "oauth/access_token");
        }
        //--------------------------------------------------------------------------------
        // Request a token from netflix
        //--------------------------------------------------------------------------------
        public static RestCall RequestToken()
        {
            return new RestCall(RestVerb.Get, BaseUrl + "oauth/request_token");
        }
        //--------------------------------------------------------------------------------
        // Get the Access Token
        //--------------------------------------------------------------------------------
        public static RestCall PermissionLogin(Connection connection, RequestToken requestToken)
        {
            string sURL = "https://api-user.netflix.com/oauth/login?oauth_token=" + requestToken.Token.AddTerm("oauth_consumer_key", connection.ConsumerKey).AddTerm("application_name", requestToken.ApplicationName).AddTerm("oauth_callback", new Uri("http://netflixauthorized.dotnetdevelopers.net/").ToString());
            return new RestCall(RestVerb.Get, sURL);
        }
        //--------------------------------------------------------------------------------
        // Get the user information from netflix
        //--------------------------------------------------------------------------------
        public static RestCall GetUsers(AccessToken accessToken)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "?");
        }
        //--------------------------------------------------------------------------------
        // Get the Instant Queue
        //--------------------------------------------------------------------------------
        public static RestCall GetQueueInstant(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/queues/instant?start_index="+startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Det the Disc Queu
        //--------------------------------------------------------------------------------
        public static RestCall GetQueueDVD(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/queues/disc?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Get the At Home Queue
        //--------------------------------------------------------------------------------
        public static RestCall GetQueueAtHome(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/at_home?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Get Rental History
        //--------------------------------------------------------------------------------
        public static RestCall GetRentalHistory(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/rental_history?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Get Rental History Shipped
        //--------------------------------------------------------------------------------
        public static RestCall GetRentalHistoryShipped(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/rental_history/shipped?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Get Rental History Returned
        //--------------------------------------------------------------------------------
        public static RestCall GetRentalHistoryReturned(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/rental_history/returned?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Get Retnal History Watched
        //--------------------------------------------------------------------------------
        public static RestCall GetRentalHistoryWatched(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/rental_history/watched?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Get Recommendations
        //--------------------------------------------------------------------------------
        public static RestCall GetRecommendations(AccessToken accessToken, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "users/" + accessToken.UserId + "/recommendations?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Get Similar Ttiles
        //--------------------------------------------------------------------------------
        public static RestCall GetSimilars(string titleId, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "catalog/titles/movies/" + titleId + "/similars?start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // Title Search
        //--------------------------------------------------------------------------------
        public static RestCall GetCatalogTitles(string term, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "catalog/titles?".AddTerm("term",term).AddTerm("start_index", startIndex.ToString()).AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }
        //--------------------------------------------------------------------------------
        // People Search
        //--------------------------------------------------------------------------------
        public static RestCall GetCatalogPeople(string term, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "catalog/people?".AddTerm("term",term).AddTerm("start_index", startIndex.ToString()).AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }

        //--------------------------------------------------------------------------------
        // Add movie to Disc Queue
        //--------------------------------------------------------------------------------
        public static RestCall PostUsersQueueDVD(AccessToken accessToken, string titleRef, DiscFormat format, int position, string ETag)
        {
            string sDiscFormat = "";

            switch (format)
            {
                case DiscFormat.DVD:
                    sDiscFormat = "0";
                    break;
                case DiscFormat.BluRay:
                    sDiscFormat = "1";
                    break;
            }

            return new RestCall(RestVerb.Post, BaseUrl + "users/" + accessToken.UserId + "/queues/disc?".AddTerm("title_ref", titleRef).AddTerm("etag", ETag).AddTerm("format", sDiscFormat).AddTerm("position", position.ToString()));
        }
        //--------------------------------------------------------------------------------
        // Add movie to Instant Queue
        //--------------------------------------------------------------------------------
        public static RestCall PostUsersQueueInstant(AccessToken accessToken, string titleRef, DiscFormat format, int position, string ETag)
        {
            return new RestCall(RestVerb.Post, BaseUrl + "users/" + accessToken.UserId + "/queues/instant?".AddTerm("title_ref",titleRef).AddTerm("&etag=", ETag).AddTerm("format", format.ToString()).AddTerm("position", position.ToString()));
        }
        //--------------------------------------------------------------------------------
        // Get Similar Ttiles
        //--------------------------------------------------------------------------------
        public static RestCall GetCatalogTitle(string titleId, int startIndex, int maxResults)
        {
            return new RestCall(RestVerb.Get, BaseUrl + "catalog/titles?" + titleId + "&start_index=" + startIndex.ToString().AddTerm("max_results", maxResults.ToString()).AddTerm("expand", "formats,synopsis,discs,episodes"));
        }

        #endregion
    }

}

namespace AddExtensions
{
    public static class RestExtensions
    {
        #region Public Extensions

        //--------------------------------------------------------------------------------
        // Public extension to add terms to the Rest commands
        //--------------------------------------------------------------------------------
        public static string AddTerm(this String sBase, string term, string value)
        {
            if (value != "")
            {
                if (sBase.EndsWith("?"))
                    sBase += term + "=" + ClrExtensions.Security.OAuth.OAuthUtility.UrlEncode(value);
                else
                    sBase += "&" + term + "=" + ClrExtensions.Security.OAuth.OAuthUtility.UrlEncode(value);

            }

            return sBase;
        }

        //--------------------------------------------------------------------------------
        // Public extension to add terms to the Rest commands
        //--------------------------------------------------------------------------------
        public static string AddTerm(this String sBase, string term, DateTimeOffset value)
        {
            if (value != null)
            {
                System.DateTimeOffset universalTime = value.ToUniversalTime();
                return AddTerm(sBase, term, universalTime.ToString("yyyy-MM-ddTHH:mm:ss"));
            }
            else
                return sBase;
        }

        #endregion
    }
}
